local function not_builder(player)
   local name = player:get_player_name()
   return not minetest.check_player_privs(name, { creative = true })
end

local function pro_player(player)
   local name = player:get_player_name()
   return minetest.check_player_privs(name, { pro_player = true })
end

minetest.register_on_joinplayer(function(player)
   local name = player:get_player_name()
   local player_attributes = player:get_meta()
   local max_hp = player_attributes:get_int('hp')
   if max_hp < 20 then
      player_attributes:set_int('hp', 20)
   else
      player:set_properties({hp_max = max_hp})
      player:set_hp(max_hp)
   end
   local privs = minetest.get_player_privs(name)
   privs.worldedit = nil
   minetest.set_player_privs(name, privs)
   player_attributes:set_string('mode', 'builder')
   lobby.suspect[name] = 0
   lobby.game[name] = 'lobby'
   lobby.voted[name] = true
   if not_builder(player) then
      local player_inv = player:get_inventory()
      player_inv:set_list('main', {})
      player:set_pos(lobby.spawn_pos)
      player_attributes:set_string('mode', 'solo')
   end
   if not pro_player(player) then
      player:set_pos(lobby.spawn_pos)
      minetest.show_formspec(name, 'lobby:help_1', lobby_help_1)
   end
   lobby.check_xp_queue(name)
end)

minetest.register_on_dieplayer(function(player)
   local name = player:get_player_name()
   local player_attributes = player:get_meta()
   local map_id = lobby.game[name]
   local mode = player_attributes:get_string('mode')
   local pos = vector.round(player:get_pos())
   player_attributes:set_string('spawn_pos', minetest.pos_to_string(pos))
   player:set_physics_override({speed=1})
   if map_id ~= 'lobby' and (mode == 'player' or mode == 'traitor') then
      local player_inv = player:get_inventory()
      player_inv:set_list('main', {})
      local traitor = lobby.traitors[map_id]
      local param2 = minetest.dir_to_facedir(player:get_look_dir())
      local pos_node = minetest.get_node(pos)
      local tone = player_attributes:get_int('tone')
      if tone == 0 then
         tone = 4
      end
      local corpse_col = 'lobby:corpse_'..tone
      if pos_node.name ~= 'air' then
         if minetest.get_item_group(pos_node.name, 'liquid') > 0 then
            minetest.set_node(pos, {name = corpse_col, param2 = param2})
            lobby.corpse_entry(pos, map_id)
         else
            local air = minetest.find_node_near(pos, 1, {'air'})
            if air then
               minetest.set_node(air, {name = corpse_col, param2 = param2})
               lobby.corpse_entry(air, map_id)
               pos = air
            end
         end
      else
         minetest.set_node(pos, {name = corpse_col, param2 = param2})
         lobby.corpse_entry(pos, map_id)
      end
      local meta = minetest.get_meta(pos)
      meta:set_string('infotext', name..'\'s Corpse.')
      player:set_nametag_attributes({
         color = {a = 0, r = 255, g = 255, b = 255}
      })
      player:set_properties({visual_size = {x = 0, y = 0}, collisionbox = {-0.3, 0.0, -0.3, 0.3, .2, 0.3}})
      player_attributes:set_string('mode', 'ghost')
      minetest.chat_send_player(name, 'You\'re now a ghost. Return to the lobby with the /lobby chat command.')
      lobby.game[name] = map_id..'_ghost'
      if name == traitor then
         minetest.log('action', 'Traitor ('..name..') just died, resulting in team win.')
         lobby.team_win(map_id)
      else
         lobby.update_maps(map_id)
      end
   elseif mode == 'solo' or mode == 'ghost' then
      local player_inv = player:get_inventory()
      player_inv:set_list('main', {})
   end
end)

minetest.register_on_respawnplayer(function(player)
   local name = player:get_player_name()
   local player_attributes = player:get_meta()
   local pos = minetest.string_to_pos(player_attributes:get_string('spawn_pos'))
   local map_id = lobby.game[name]
   minetest.log('action', name..' just respawned on '..map_id)
   local mode = player_attributes:get_string('mode')
   player:set_armor_groups({immortal=1})
   minetest.chat_send_player(name, 'You are immortal for 10 seconds.')
   minetest.after(10, function()
      player:set_armor_groups({})
      minetest.chat_send_player(name, 'Immortallity has ended.')
   end)
   if map_id ~= 'lobby' and mode == 'ghost' then
      local real_id = string.sub(map_id, 0, -7)
      if lobby.map[real_id] and lobby.map[real_id] > 1 then
         player:set_pos(pos)
         return true
      else
         player:set_pos(lobby.spawn_pos)
      end
   elseif mode == 'builder' then
      player:set_pos(pos)
      return true
   else
      local player_attributes = player:get_meta()
      player:set_nametag_attributes({
         color = {a = 255, r = 255, g = 255, b = 255}
      })
      player:set_properties({visual_size = {x = 10, y = 10}, collisionbox = {-0.3, 0.0, -0.3, 0.3, 1.7, 0.3}})
      player:set_pos(lobby.spawn_pos)
      player_attributes:set_string('mode', 'solo')
      return true
   end
end)

minetest.register_on_leaveplayer(function(player, timed_out)
   local name = player:get_player_name()
   local map_id = lobby.game[name]
   local player_attributes = player:get_meta()
   local mode = player_attributes:get_string('mode')
   if map_id ~= 'lobby' and (mode == 'player' or mode == 'traitor') then
      local game_data = lobby.savedata.data[map_id]
      local map_name = game_data['map_name'] or map_id
      local traitor = lobby.traitors[map_id]
      minetest.chat_send_all('somebody quit the '..map_name..' level')
      local player_inv = player:get_inventory()
      player_inv:set_list('main', {})
      lobby.update_maps(map_id)
      if traitor == name then
         lobby.team_win(map_id)
      end
   end
end)
